package qc.module.demo.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.enums.ResourceStatusFlagEnum;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.module.demo.dto.user.UserAddDto;
import qc.module.demo.dto.user.UserDto;
import qc.module.demo.dto.user.UserQueryConditionDto;
import qc.module.demo.entity.DeptUser;
import qc.module.demo.entity.User;
import qc.module.demo.mapper.UserMapper;
import qc.module.demo.repository.DeptUserRepository;
import qc.module.demo.repository.UserRepository;

import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;

@Service
public class UserService {
    private UserRepository repository;

    @Autowired
    public void setUserRepository(UserRepository repository) {
        this.repository = repository;
    }

    private DeptUserRepository deptUserRepository;

    @Autowired
    public void setDeptUserRepository(DeptUserRepository deptUserRepository) {
        this.deptUserRepository = deptUserRepository;
    }

    private DeptService deptService;

    @Autowired
    public void setDeptService(DeptService deptService) {
        this.deptService = deptService;
    }

    /**
     * 根据查询条件查询用户信息
     *
     * @param condition 查询条件
     * @return 用户集合
     * @author QuCheng Tech
     * @since 2023/6/1
     */
    public List<UserDto> query(UserQueryConditionDto condition) {
        //单表查询
        //查询条件可以为空，表示查询所有用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        if (condition != null) {
            //判断是否有状态条件：2表示启用，3表示禁用，输入其他表示查询所有
            boolean hasStatusCondition = false;
            if (condition.getStatus() == 0x2)
                wrapper.eq(User::getFlag, ResourceStatusFlagEnum.NORMAL);
            if (condition.getStatus() == 0x3)
                wrapper.eq(User::getFlag, ResourceStatusFlagEnum.DISABLE);
            //判断是否有关键字条件，如果有需要匹配用户名称、登录名、手机号中的一种
            if (!StringUtils.isBlank(condition.getKeywords())) {
                wrapper.and(q -> {
                    q.like(User::getName, condition.getKeywords()).or().like(User::getCode, condition.getKeywords()).or().like(User::getPhone, condition.getKeywords());
                });
            }
        }
        //排序
        wrapper.orderByAsc(User::getName);
        //查询
        List<User> ens = repository.selectList(wrapper);

        if (ens != null && ens.size() > 0x0) {
            //demo作为演示作用，在此获取用户与部门关联关系，获取每个用户对应的第1个部门作为返回结果
            LambdaQueryWrapper<DeptUser> deptUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
            List<DeptUser> deptUsers = deptUserRepository.selectList(deptUserLambdaQueryWrapper);
            Hashtable<Integer, Integer> userIdAndDeptIds = new Hashtable<>();
            if (deptUsers != null && deptUsers.size() > 0x0) {
                for (DeptUser item : deptUsers) {
                    if (!userIdAndDeptIds.containsKey(item.getUserid()))
                        userIdAndDeptIds.put(item.getUserid(), item.getDeptid());
                }
            }

            //映射中需要处理用户状态和部门ID，在此单独进行转换映射
            //return UserMapper.MAPPER.toDtoList(ens);
            List<UserDto> result = new ArrayList<>();

            for (User en : ens) {
                UserDto dto = UserMapper.MAPPER.toDto(en);

                dto.setEnable(false);
                if (en.getFlag() == ResourceStatusFlagEnum.NORMAL)
                    dto.setEnable(true);

                if (userIdAndDeptIds.containsKey(en.getId()))
                    dto.setDeptid(userIdAndDeptIds.get(en.getId()));

                result.add(dto);
            }

            return result;
        }

        ////多表联合查询
        //MPJLambdaWrapper<User> wrapper = new MPJLambdaWrapper<User>()
        //        .select(User::getId, User::getName, User::getCode, User::getPhone, User::getEnable, User::getExpiredtm)
        //        .select(DeptUser::getDeptid)
        //        .innerJoin(DeptUser.class, DeptUser::getUserid,User::getId);
        ////.leftJoin(User.class, User::getId, DeptUser::getUserid);
        //if (condition != null) {
        //    //判断是否有状态条件：2表示启用，3表示禁用，输入其他表示查询所有
        //    boolean hasStatusCondition = false;
        //    if (condition.getStatus() == 0x2 || condition.getStatus() == 0x3)
        //        wrapper.eq(User::getEnable, condition.getStatus() == 0x2 ? true : false);
        //    //判断是否有关键字条件，如果有需要匹配用户名称、登录名、手机号中的一种
        //    if (!StringUtils.isBlank(condition.getKeywords())) {
        //        wrapper.and(q -> {
        //            q.like(User::getName, condition.getKeywords()).or().like(User::getCode, condition.getKeywords()).or().like(User::getPhone, condition.getKeywords());
        //        });
        //    }
        //}
        ////排序
        //wrapper.orderByAsc(User::getName);
        //
        ////List<UserDto> result = deptUserRepository.selectJoinList(UserDto.class, wrapper);
        //List<UserDto> result = repository.selectJoinList(UserDto.class, wrapper);
        //if (result != null && result.size() > 0x0)
        //    return result;

        return null;
    }

    /**
     * 获取指定ID的用户信息
     *
     * @param userId 用户ID
     * @return 用户信息
     * @author QuCheng Tech
     * @since 2023/6/1
     */
    public UserDto get(int userId) throws QCPromptException {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId, userId);

        User user = repository.selectOne(wrapper);

        if (user != null) {
            UserDto result = UserMapper.MAPPER.toDto(user);

            //用户的状态赋值
            result.setEnable(false);
            if (user.getFlag() == ResourceStatusFlagEnum.NORMAL)
                result.setEnable(true);

            //获取用户的部门信息
            LambdaQueryWrapper<DeptUser> deptUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
            deptUserLambdaQueryWrapper.eq(DeptUser::getUserid, user.getId());
            List<DeptUser> deptUsers = deptUserRepository.selectList(deptUserLambdaQueryWrapper);
            if (deptUsers != null && deptUsers.size() > 0x0) {
                result.setDeptid(deptUsers.get(0x0).getDeptid());
            }

            return result;
        }

        throw new QCPromptException("指定的用户信息不存在");
    }

    /**
     * 新增用户
     *
     * @param dto 用户信息
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/6/1
     */
    public String add(UserAddDto dto) {
        if (dto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getName()))
            return QCUnifyReturnValue.Warn("用户名称不能为空");
        if (!StringUtils.isBlank(dto.getCode())) {
            //判断用户编码不能重复
            if (isCodeHasExist(dto.getCode(), 0x0))
                return QCUnifyReturnValue.Warn("用户编码已存在，用户编码不能相同");
        }
        if (!StringUtils.isBlank(dto.getPhone())) {
            //判断手机号不能重复
            if (isPhoneHasExist(dto.getPhone(), 0x0))
                return QCUnifyReturnValue.Warn("手机号已存在，手机号不能相同");
        }

        //判断部门是否存在
        if (!deptService.hasIdExist(dto.getDeptid()))
            return QCUnifyReturnValue.Warn("指定的部门信息不存在");

        //DTO转换为Entity
        User en = UserMapper.MAPPER.toEntity(dto);
        //新增时需设置ID
        en.setId(genereateId());
        //判断过期时间
        if (!StringUtils.isBlank(dto.getExpiredtm())) {
            Date expireTime = DateUtil.parseDate(dto.getExpiredtm());
            en.setExpiredtm(expireTime);
        }
        //设置标记
        if (dto.isEnable())
            en.setFlag(ResourceStatusFlagEnum.NORMAL);
        else
            en.setFlag(ResourceStatusFlagEnum.DISABLE);
        //新增时设置默认密码
        en.setPassword("10ed1697617fe7758b4236d5b791286c");

        if (repository.insert(en) < 0x1)
            return QCUnifyReturnValue.Warn("新增用户失败");

        //添加用户与部门关联关系
        DeptUser enDeptUser = new DeptUser();
        enDeptUser.setUserid(en.getId());
        enDeptUser.setDeptid(dto.getDeptid());
        deptUserRepository.insert(enDeptUser);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改用户信息
     *
     * @param dto 用户信息
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/6/1
     */
    public String update(UserDto dto) {
        if (dto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        if (dto.getId() < 0x1)
            //if (StringUtils.isBlank(dto.getId()))
            return QCUnifyReturnValue.Warn("用户ID不能为空");
        if (StringUtils.isBlank(dto.getName()))
            return QCUnifyReturnValue.Warn("用户名称不能为空");

        //DTO转换为Entity
        User en = UserMapper.MAPPER.toEntity(dto);
        //判断修改的用户信息是否存在
        if (!hasIdExist(en.getId()))
            return QCUnifyReturnValue.Warn("修改的用户ID不存在");

        //判断过期时间，修改时可以将原设置有过期时间修改为无
        if (!StringUtils.isBlank(dto.getExpiredtm())) {
            Date expireTime = DateUtil.parseDate(dto.getExpiredtm());
            en.setExpiredtm(expireTime);
        } else {
            en.setExpiredtm(null);
        }
        //设置标记
        if (dto.isEnable())
            en.setFlag(ResourceStatusFlagEnum.NORMAL);
        else
            en.setFlag(ResourceStatusFlagEnum.DISABLE);

        if (!StringUtils.isBlank(dto.getCode())) {
            //判断用户编码不能重复
            if (isCodeHasExist(dto.getCode(), en.getId()))
                return QCUnifyReturnValue.Warn("用户编码已存在，用户编码不能相同");
        }
        if (!StringUtils.isBlank(dto.getPhone())) {
            //判断手机号不能重复
            if (isPhoneHasExist(dto.getPhone(), en.getId()))
                return QCUnifyReturnValue.Warn("手机号已存在，手机号不能相同");
        }

        //判断部门是否存在
        if (!deptService.hasIdExist(dto.getDeptid()))
            return QCUnifyReturnValue.Warn("指定的部门信息不存在");

        repository.updateById(en);

        //删除用户与部门关联关系
        LambdaUpdateWrapper<DeptUser> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DeptUser::getUserid, en.getId());
        deptUserRepository.delete(wrapper);
        //添加用户与部门关联关系
        DeptUser enDeptUser = new DeptUser();
        enDeptUser.setUserid(en.getId());
        enDeptUser.setDeptid(dto.getDeptid());
        deptUserRepository.insert(enDeptUser);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除用户
     *
     * @param userId 用户ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/6/1
     */
    public String delete(int userId) {
        if (!hasIdExist(userId))
            return QCUnifyReturnValue.Warn("删除的用户ID不存在");

        repository.deleteById(userId);

        //删除用户与部门关联关系
        LambdaUpdateWrapper<DeptUser> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DeptUser::getUserid, userId);
        deptUserRepository.delete(wrapper);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 判断指定的ID是否存在
     *
     * @param id ID
     * @return true表示已存在，false表示不存在
     * @author QuCheng Tech
     * @since 2023/5/26
     */
    public boolean hasIdExist(Integer id) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId, id);

        User en = repository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }

    /**
     * @param code 登录编码
     * @param id   ID，新增时设置ID为0，修改时设置ID为记录ID
     * @return true表示名称已存在，false表示名称不存在
     * @author QuCheng Tech
     * @since 2023/5/25
     */
    boolean isCodeHasExist(String code, Integer id) {
        //验证名称是否重复条件：name=name and id<>id
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getCode, code);
        wrapper.ne(User::getId, id);

        User en = repository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }

    /**
     * @param phone 手机号
     * @param id    ID，新增时设置ID为0，修改时设置ID为记录ID
     * @return true表示名称已存在，false表示名称不存在
     * @author QuCheng Tech
     * @since 2023/5/25
     */
    boolean isPhoneHasExist(String phone, Integer id) {
        //验证名称是否重复条件：name=name and id<>id
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getCode, phone);
        wrapper.ne(User::getId, id);

        User en = repository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }

    /**
     * 生成记录ID，获取数据库表中的最大记录ID+1
     *
     * @return 生成记录ID
     * @author QuCheng Tech
     * @since 2023/5/25
     */
    Integer genereateId() {
        Integer maxRecordId = getMaxId();
        return maxRecordId + 1;
    }

    /**
     * 获取数据库表中的最大ID值，没有记录时返回0
     *
     * @return 返回数据库表中的最大ID值
     * @author QuCheng Tech
     * @since 2023/5/25
     */
    Integer getMaxId() {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(User::getId);
        wrapper.orderByDesc(User::getId);
        User en = repository.selectOne(wrapper);
        if (en != null)
            return en.getId();

        return 0x0;
    }
}
